#ifndef PARSER
#define PARSER

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <map>

#define output "test.txt"
using namespace std;

typedef map<string, vector<string> > MapType;
typedef map<string, vector<vector<string> > > ThreeDMapType;
typedef map<string, MapType> parsetable;

class Parser {
public:
	Parser(map<string, vector<string> > rules_, string input_file_, vector<
	       string> tokens, vector<string> nts, string start_state);
	~Parser();
	void parse();

private:
	map<string, vector<string> > rules;
	string input_file;
	vector<string> listOfTokens, listOfNTs;
	string start_state;
	parsetable vidtable; // key = NonTerminal
	MapType FirstSet, FollowSet; // map to vector<string>
	ThreeDMapType TDData; // map to vector<vector<string>>

	void handleLeftRecursion(string main_rule, vector<string> &orig_rule,
			vector<string> &new_rule, vector<int> targs);
	void printGrammar();
	void createParseTable();
	void removeLeftRecursion();
	void removeLeftFactoring();
	void fixLeftFactoring(vector<vector<string> > &original, vector<vector<
			string> > &new_rule, string common, string &new_name);
	void createFollowSets();
	void createFirstSets();
	void checkInput();
	void decode(vector<string> &stack, string rule, string input);
	string getTableContents(string rule, string token);
	bool checkForEpsilon(vector<string> &vec);
	void eraseEpsilon(vector<string> &vec);
	bool isTerminal(string toTest);
	bool checkIfContains(vector<string> &firstSet, string toCheck);
	void eliminateSpaces(vector<string> &vec);

	void print2DMap(MapType &themap);
	void print3DMap(ThreeDMapType &TheData);
	void printToFile(parsetable &table);
	void printParseTable(parsetable &table);
	void printVector(vector<string> &vec);
	void printVector(vector<vector<string> > &vec);


	void make3DData();
};

#endif
